@using Radzen
@using Radzen.Blazor
@using Radzen.Blazor.Rendering
@inject DialogService DialogService

@{
    var points = new Dictionary<AppointmentData, double>();

    // delaci check usage
    var year = StartDate.AddDays(7).Year;

    DateTime date = StartDate.AddDays(7);
    DateTime realstart = StartDate;
    int daysinmonth;
}


<div class="rz-view rz-year-view">
<div class="rz-display-flex rz-row rz-align-items-normal rz-justify-content-space-between">
    @for (int month = 0; month < 12; month++)
    {
        int offSetMonth = ((month + (int)StartMonth) % 12) + 1;
        int curYear = year + (offSetMonth <= month ? 1 : 0);
        realstart = new DateTime(curYear, offSetMonth, 1);
        daysinmonth = DateTime.DaysInMonth(curYear, offSetMonth);
        date = realstart.StartOfMonth().StartOfWeek(Scheduler.Culture);
        var currentDate = date;
        var currentMonth = month;
        var startMonth = realstart;

        <div class="rz-year-month rz-display-flex rz-flex-column rz-col-12 rz-col-sm-6 rz-col-md-4 rz-col-lg-3"
                 tabindex="0" @onkeydown="@(args => OnKeyPress(args))" @onkeydown:preventDefault="@preventKeyPress" @onkeydown:stopPropagation
                 @onfocus=@(args => {CurrentDate = currentDate; CurrentMonth = currentMonth; })>

            <div class="rz-slot-header rz-pb-2" @onclick=@(args => OnMonthClick(startMonth))>
                <span class="rz-text-subtitle1">
                    @realstart.ToString("MMMM yyyy", Scheduler.Culture)
                </span>
            </div>

            <div class="rz-view-header">
                @for (var dateheader = StartDate; dateheader <= StartDate.EndOfWeek(Scheduler.Culture); dateheader = dateheader.AddDays(1))
                {
                    <div class="rz-slot-header">
                        @dateheader.ToString("ddd", Scheduler.Culture).Substring(0,1)
                    </div>
                }
            </div>

            @for (var row = 0; row < 6; row++)
            {
                <div class="rz-week">
                    <div class="rz-events">
                        <div class="rz-slots">
                            @for (var col = 0; col < 7; col++)
                            {
                                var day = date.AddDays((row * 7) + col);
                                var appointments = AppointmentsInRange(day, day.AddDays(1));
                                var excessCount = appointments.Count();
                                string classname = $"rz-slot-title {(day.Month != offSetMonth ? "rz-other-month" : "")} {(excessCount > 0 ? "rz-has-appointments" : "")} {(day == CurrentDate && month == CurrentMonth ? " rz-state-focused" : "")}".Trim();

                                    <div @onclick=@(args => OnListClick(day, appointments)) @attributes=@Attributes(day, "rz-slot")>
                                        <div class="@classname">
                                            @day.Day
                                        </div>
                                    </div>
                                }
                        </div>
                    </div>
                </div>
            }
        </div>
    }
</div>
</div>

@code {
    [Parameter]
    public DateTime StartDate { get; set; }

    [Parameter]
    public DateTime EndDate { get; set; }

    [Parameter]
    public Month StartMonth { get; set; }

    [Parameter]
    public int MaxAppointmentsInSlot { get; set; }

    [Parameter]
    public string MoreText { get; set; }

    [Parameter]
    public string NoDayEventsText  { get; set; }

    [CascadingParameter]
    public IScheduler Scheduler { get; set; }

    [Parameter]
    public IEnumerable<AppointmentData> Appointments { get; set; }

    IDictionary<string, object> Attributes(DateTime start, string className)
    {
        var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1), () => AppointmentsInRange(start, start.AddDays(1)));
        attributes["class"] = ClassList.Create(className).Add(attributes).ToString();
        return attributes;
    }

    async Task OnAppointmentClick(AppointmentData data)
    {
        await Scheduler.SelectAppointment(data);
    }

    private AppointmentData[] AppointmentsInRange(DateTime start, DateTime end)
    {
        if (Appointments == null)
        {
            return Array.Empty<AppointmentData>();
        }

        return Appointments.Where(item => Scheduler.IsAppointmentInRange(item, start, end)).OrderBy(item => item.Start).ThenByDescending(item => item.End).ToArray();
    }

    async Task OnMonthClick(DateTime monthStart)
    {
        await Scheduler.SelectMonth(monthStart, AppointmentsInRange(monthStart, monthStart.EndOfMonth()));
    }

    async Task OnListClick(DateTime date, IEnumerable<AppointmentData> appointments)
    {
        bool preventDefault = await Scheduler.SelectSlot(date, date.AddDays(1), appointments);

        if(!preventDefault)
        {
        if (appointments.Count() > 0)
        {
            await DialogService.OpenAsync(date.ToShortDateString(), ds =>
    @<div class="rz-event-list">
        <CascadingValue Value=@Scheduler>
            @foreach (var item in appointments)
            {
                <Appointment Data=@item Click="OnListEventClick" />
            }
        </CascadingValue>
    </div>
        );

        }
        else
        {
            await DialogService.OpenAsync(date.ToShortDateString(), ds =>
    @<div class="rz-event-list">
        @(NoDayEventsText)
    </div>
    );

        }
        }
    }

    async Task OnListEventClick(AppointmentData data)
    {
        DialogService.Close();

        await OnAppointmentClick(data);
    }

    DateTime CurrentDate;
    int CurrentMonth;

    bool preventKeyPress = false;

    async Task OnKeyPress(KeyboardEventArgs args)
    {
        var key = args.Code != null ? args.Code : args.Key;

        if (key == "ArrowLeft" || key == "ArrowRight" || key == "ArrowUp" || key == "ArrowDown")
        {
            var days = key == "ArrowLeft" || key == "ArrowRight" ? 1 : 7;
            CurrentDate = CurrentDate.AddDays(key == "ArrowLeft" || key == "ArrowUp" ? -days : days);
            preventKeyPress = true;
        }
        else if (key == "Enter")
        {
            await OnListClick(CurrentDate, AppointmentsInRange(CurrentDate, CurrentDate.AddDays(1)));

            preventKeyPress = true;
        }
        else
        {
            preventKeyPress = false;
        }
    }
}
